﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit;
using NUnit.Framework;
using System.Collections;


namespace TreeLib
{
    [TestFixture]
    class ParamTEst
    {
        [SetUp]
        public void Initialize()
        {
            
            foreach (object[] obj in TreeFuncions)
            {
                BinaryTree u = (BinaryTree)obj[0];
                if (u.itemCount() > 1) 
                {
                    obj[0] = Many();
                }           
            }
            
        }
        static object[] TreeCases =
        {
            new object[] { Many(), Manyexp()},
            new object[] { One(), Oneexp()},
            new object[] { Nullf(), Nullexp()}
        };     
        static object[] TreeFuncions =
        {
            new object[] { Many(),3},
            new object[] { One(),1},
            new object[] { Nullf(),0}
        }; 
        static BinaryTree Nullf()
        {
            BinaryTree target = new BinaryTree();          
            return target;
        }
        static Element Nullexp()
        {
            Element expected = null;
            return expected;
        }
        static BinaryTree One()
        {
            BinaryTree target = new BinaryTree();
            target.add(4);            
            return target;
        }
        static Element Oneexp()
        {
            Element expected = new Element(4);           
            return expected;
        }
        static BinaryTree Many() 
        {
            BinaryTree target = new BinaryTree();
            target.add(4);
            target.add(3);
            target.add(1);
            target.add(7);
            return target;
        }
      static  Element Manyexp() 
        {
            Element expected = new Element(4);
            expected.left = new Element(3);
            expected.left.left = new Element(1);
            expected.right = new Element(7);
            return expected;
        }
        bool compareEl(Element a, Element b)
      {
            bool ret = false;
            if (a == null & b == null)
            { ret = true; }
            else
            {
                if (a.value == b.value)
                {
                    ret = true;
                    if (a.left != null)
                    {
                        if (b.left != null)
                        {
                            ret = compareEl(a.left, b.left);
                        }
                        else
                        {
                            ret = false;
                        }
                    }
                    if (a.right != null)
                    {
                        if (b.right != null)
                        {
                            ret = compareEl(a.right, b.right);
                        }
                        else
                        {
                            ret = false;
                        }
                    }

                }
            }
            return ret;
        }
        [Test, TestCaseSource("TreeCases")]
        public void Get(BinaryTree target, Element expected)
        {
            Assert.IsTrue(compareEl(target.get(4), expected)); 
        }

        [Test, TestCaseSource("TreeFuncions")]
        public void Height(BinaryTree target, int expected)
        {            
            Assert.AreEqual(expected, target.height());
        }
        [Test, TestCaseSource("TreeFuncions")]
        public void Width(BinaryTree target, int expected)
        {
            Assert.AreEqual(expected, target.width());
        }
        [Test, TestCaseSource("TreeFuncions")]
        public void Count(BinaryTree target, int expected)
        {
            if (expected == 3) 
            {
                expected = 4;
            }
            Assert.AreEqual(expected, target.itemCount());
        }
        [Test, TestCaseSource("TreeFuncions")]
        public void tieCount(BinaryTree target, int expected)
        {
            if (expected == 3)
            {
                expected = 2;
            }
            if (expected == 1)
            {
                expected = 0;
            }
            Assert.AreEqual(expected, target.tieCount());
        }
        [Test, TestCaseSource("TreeFuncions")]
        public void leafCount(BinaryTree target, int expected)
        {
            if (expected == 3)
            {
                expected = 2;
            }            
            Assert.AreEqual(expected, target.LeavCount());
        }
        [Test, TestCaseSource("TreeFuncions")]
        public void Sort(BinaryTree target, int exp)
        {
             List<int> expected=null;
             switch (exp) 
             {
                 case 3: expected = new List<int>() { 1, 3, 4, 7 }; break;
                 case 1: expected = new List<int>() { 4 }; break;
                 default: expected = new List<int>();  break;
             }

            Assert.AreEqual(expected, target.getSorted());
        }
        [Test, TestCaseSource("TreeFuncions")]
        public void rev(BinaryTree target, int exp)
        {
            Element expected = null;
            switch (exp)
            {
                case 3: expected = new Element(4);
                    expected.left = new Element(7);
                    expected.right = new Element(3);
                    expected.right.right = new Element(1); break;
                case 1: expected = new Element(4); break;
                default: break;
            }
            target.reverse();
            Assert.IsTrue(compareEl(target.get(4), expected));
        } 
    }
}
